package tjs.study.notes.dotest.disruptor.apiLog.config;

/**
 * Created by Nicky.Tang on 2022/9/29 下午2:48
 *
 * @since 02.12.10
 */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import tjs.study.notes.dotest.disruptor.apiLog.service.WriteLogService;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//@Component // 加上这个会导致下面urlPatterns失效 改为启动类添加@ServletComponentScan注解
@ConditionalOnProperty(name = "shsnc.project.disruptor.enable", matchIfMissing = false, havingValue = "true")
@WebFilter(filterName = "traceLogFilter", urlPatterns = "/openapi/*")
public class ApiLogFilter implements Filter, Ordered {
    private static final Logger logger = LoggerFactory.getLogger(ApiLogFilter.class);
    @Autowired
    private WriteLogService writeLogService;

    public ApiLogFilter() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// request 的inputStream和response 的outputStream默认情况下是只能读一次， 不可重复读
        ContentCachingRequestWrapper wrapperRequest = new ContentCachingRequestWrapper((HttpServletRequest) request);
        ContentCachingResponseWrapper wrapperResponse = new ContentCachingResponseWrapper((HttpServletResponse) response);
        Object errMsg = null;
        long startTime = System.currentTimeMillis();
        try {
            chain.doFilter(wrapperRequest, wrapperResponse);
        } catch (Throwable ex) {
            errMsg = ex.getMessage();
            throw ex;
        } finally {
            try {
                String accessKey = wrapperRequest.getHeader("access-key");
                //if (StringUtils.isNotBlank(accessKey) ) {
                writeLogService.sendWriteLog(accessKey, errMsg, startTime, wrapperRequest, wrapperResponse);
                //}
            } catch (Throwable e) {
                logger.error("sendWriteLog", e);
            }
            wrapperResponse.copyBodyToResponse();// 将响应写回输出流
        }

    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE;
    }
}